#include "classid.h"

ClassId::ClassId(const string& name, const string& extension, ClassId* parent, Instance*(*allocate)(const string&,ClassId*)):
mName(name),
mExtension(extension),
mAllocate(allocate)
{
    if(!parent)
        mRank = sHierarchy.set_head(this);
    else
        mRank = sHierarchy.append_child(parent->mRank, this);
    if(!boost::filesystem::exists(getPathName()))
        boost::filesystem::create_directory(getPathName());
}

ClassId::~ClassId()
{
    sHierarchy.erase(mRank);
}

string ClassId::getPathName()
{
    tree<ClassId*>::iterator parent = sHierarchy.parent(mRank);

    if(parent != 0) {
        if(*parent)
            return (*parent)->getPathName() + mName + "/";
    }
    return mName + "/";
}

Uint32 ClassId::getHash()
{
    static hash<string> string_hash;

    return string_hash(getPathName());
}

ClassId* ClassId::getFromPathName(const string& pathname)
{
    static hash<string> string_hash;

    return getFromHash(string_hash(pathname));
}

ClassId* ClassId::getFromHash(Uint32 hash)
{
    tree<ClassId*>::iterator i = ClassId::sHierarchy.begin();

    while(i != sHierarchy.end()) {
        if(*i)
            if(hash == (*i)->getHash())
                return *i;
        ++i;
    }
    return 0;
}

Instance* ClassId::allocate(const string& name, ClassId* classId)
{
    assert(mAllocate);
    assert(classId);
    return mAllocate(name, classId);
}
